package com.springframework.boot.awesome.annotation.arch.util;

import com.springframework.boot.awesome.annotation.arch.entity.FTPConfig;
import com.jcraft.jsch.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.TimeoutException;

public class SFTPUtil {
    private static JSch jsch = null;
    private static ChannelSftp sftp = null;
    private static Session session;

    public static void monitorFile(long frequency, Method handleFileMethod, Object obj, FTPConfig ftpConfig, long timeout)
            throws TimeoutException, InterruptedException, JSchException, SftpException, InvocationTargetException,
            IllegalAccessException {
        try{
            long startTime = System.currentTimeMillis();
            String host = ftpConfig.getIp();
            int port = Integer.valueOf(ftpConfig.getPort());
            String username = ftpConfig.getUsername();
            String password = ftpConfig.getPassword();
            ChannelSftp connect = connect(host, port, username, password);

            while (true){
                Vector vector = connect.ls(ftpConfig.getPath());
                Iterator iterator = vector.iterator();
                List<String> fileNameList = new ArrayList();
                while (iterator.hasNext()){
                    String tempFileName = String.valueOf(iterator.next());
                    String[] tempStrArgs = tempFileName.split(" ");
                    String fileName = tempStrArgs[tempStrArgs.length - 1];
                    if(!fileName.equals(".") && !fileName.equals("..")){
                        fileNameList.add(fileName);
                    }
                }
                Object[] arguments = new Object[]{fileNameList};
                Object flag = handleFileMethod.invoke(obj, arguments);
                if(flag instanceof Boolean && (boolean)flag){
                    break;
                }
                if(System.currentTimeMillis() - startTime > timeout){
                    throw new TimeoutException("file is not exists, millisecondsTimeout: " + timeout);
                }else{
                    Thread.sleep(frequency);
                }
            }
        }finally {
            logout();
        }
    }

    public static ChannelSftp connect(String host, int port, String username,
                               String password) throws JSchException {
        jsch = new JSch();
        jsch.getSession(username, host, port);
        session = jsch.getSession(username, host, port);
        session.setPassword(password);
        Properties sshConfig = new Properties();
        sshConfig.put("StrictHostKeyChecking", "no");
        session.setConfig(sshConfig);
        session.connect();
        Channel channel = session.openChannel("sftp");
        channel.connect();
        sftp = (ChannelSftp) channel;
        return sftp;
    }

    private static void logout(){
        if (sftp != null) {
            if (sftp.isConnected()) {
                sftp.disconnect();
            }
        }
        if (session != null) {
            if (session.isConnected()) {
                session.disconnect();
            }
        }
    }
}
